package yxy.game.pm2.module.worldboss;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;

import yxy.cherry.battle.module.Position;
import yxy.cherry.battle.module.record.FighterSide;
import yxy.cherry.battle.module.record.result.StatisticFighter;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.herodata;
import yxy.cherry.data.bean.menghuoboss;
import yxy.cherry.data.bean.menghuorankreward;
import yxy.cherry.data.bean.menghuoreward;
import yxy.cherry.data.string.GameString;
import yxy.game.pm2.Result;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.Format.FormatType;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.currency.Currencies;
import yxy.game.pm2.bean.module.rank.RankEntry;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.message.BattleMessage;
import yxy.game.pm2.message.WorldBossMessage;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.battle.*;
import yxy.game.pm2.module.mail.MailHandle;
import yxy.game.pm2.module.mail.MailTypeEnum;

public class WorldBossHandle {

	private String code() {
		return BattleType.MENGHUO.name();
	}

	/** 处理战斗 */
	public Result battleResponseExecute(WorldBossPlayer worldBossPlayer, WorldBossModule worldBossModule,
			WorldBossMessage.WorldBossChanllengeResponse.Builder response) throws Exception {
		String playerCode = worldBossPlayer.getPlayerCode();
		menghuoboss data = data();

		BattleHandle battleHandle = new BattleHandle();

		BattleModule battleModule = BattleModule.create(playerCode);
		battleModule.setType(BattleType.MENGHUO);
		battleModule.setCode(code());

		// 玩家的team
		TeamModule teamA = battleHandle.teamPlayer(playerCode, FormatType.普通);
		battleModule.setTeamA(teamA);

		// Boss的team
		TeamModule teamB = teamBoss(data);
		battleModule.setTeamB(teamB);

		BattleMessage.BattleExecuteResponse res = new BattleHandle().battleResponseExecute(battleModule //
				, data.getRound()
				, false, null);

		// 计算伤害
		long damage = 0;
		for (StatisticFighter fighter : battleModule.getStatistics()) {
			if (fighter.getPos().getSide().equals(FighterSide.RIGHT)) {
				damage += fighter.getHut();
			}
		}

		Currencies rewards = handleDamage(worldBossPlayer, worldBossModule, damage);

		// 封装消息
		response.setBattleResp(res);// 录像
		response.setBattleResult(battleModule.getBattleResult().getNumber());// 战果
		response.setDamage(damage);
		response.addAllRewards(new CurrencyHandle().packItems(rewards));

		return Result.Success;
	}

	/** 处理扫荡 */
	public Result bossSweep(WorldBossPlayer worldBossPlayer, WorldBossModule worldBossModule,
			WorldBossMessage.WorldBossChanllengeQuickResponse.Builder response) {
		if (!worldBossPlayer.getCode().equals(worldBossModule.getCode()) || worldBossPlayer.getDamage() <= 0) {
			return Result.ParamError;// 玩家没有对boss有上一次的伤害记录
		}

		// 计算伤害
		long damage = worldBossPlayer.getDamage();
		Currencies rewards = handleDamage(worldBossPlayer, worldBossModule, damage);

		response.setDamage(damage);
		response.addAllRewards(new CurrencyHandle().packItems(rewards));

		return Result.Success;
	}

	/** 处理伤害 */
	private Currencies handleDamage(WorldBossPlayer worldBossPlayer, WorldBossModule worldBossModule, long damage) {
		String playerCode = worldBossPlayer.getPlayerCode();
		menghuoboss data = data();

		// 伤害排名记录
		RankWorldBoss rankBoss = RankWorldBoss.getRank(playerCode);
		rankBoss.addAndSet(playerCode, damage);
		// 个人玩家记录
		worldBossPlayer.setDamage(damage);
		worldBossPlayer.setTimes(worldBossPlayer.getTimes() + 1);
		worldBossModule.setTotalDamage(worldBossModule.getTotalDamage() + damage);

		worldBossPlayer.set();
		worldBossModule.set();

		// 联盟BOSS挑战奖励
		Currencies rewards = new Currencies(Currency.create(data.getRewardtype(), data.getRewardid(), data.getRewardnum()));
		new CurrencyHandle().addCurrency(playerCode, CCReason.七擒孟获, rewards);
		return rewards;
	}

	public TeamModule teamBoss(menghuoboss bossdata) {
		TeamModule team = new TeamModule();
		// 武将
		Position position = Position.FM;
		int heroid = bossdata.getFront();
		int level = bossdata.getGrade();
		int anger = 0;
		int stage = 0;
		int star = 0;

		//如果找不到heroid默认不变  stage和star为0
		HashMap<String, Integer> map = BattleHandle.addStarAndStage(heroid, stage, star, level);
		heroid = map.get("heroid");
		stage = map.get("stage");
		star = map.get("star");

		FighterModule fighterModule = FighterModule.create(heroid, level, stage, star, anger);
		fighterModule.setProperty(PropertyModule.create(BattleHandle.getOppositePropertyData(heroid, level, stage, star, anger)));


		fighterModule.getProperty().setLife(10000000000L);
		fighterModule.getProperty().setLifeAdd(0);
		team.addfighter(position, fighterModule);

		// 信息
		herodata _herodata = DataCenter.getData(heroid, herodata.class);
		team.setName(_herodata.getName());
		team.setHead(bossdata.getHeadid());
		team.setPower(88000000000L);

		return team;
	}

	public menghuoboss data() {
		menghuoboss data = DataCenter.getData(1, menghuoboss.class);
		return data;
	}

	public Result checkWorldLevel(AreaBean areaBean) {
		int worldLevel = areaBean.getWorldLevel();
		if (worldLevel < 1) {
			return Result.WorldBossWorldLevel;// 世界等级不足
		}
		if (!isOpen(DateTime.now())) {
			return Result.WorldBossNotOpen;// 活动尚未开启
		}
		return Result.Success;
	}

	// 时间控制===========================================================================

	public void update() {
		DateTime now = DateTime.now();
		for (AreaBean areaBean : AreaBean.all()) {
			WorldBossModule module = WorldBossModule.get(areaBean.getAreaId());
			try {
				if (module.tryLock()) {
					boolean preState = isOpen(module.getUpdateTime());
					boolean nowState = isOpen(now);
					if (preState == nowState) {
						continue;
					}
					module.setUpdateTime(now);
					module.setOpening(nowState);
					if (nowState) {
						open(areaBean, module, now);
					} else {
						// 关闭活动 派发邮件奖励
						settle(areaBean, module);
					}
					module.set();
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				module.unlock();
			}
		}
	}

	/** 时间判断：每周二、四、六的上午8点——21点 开启 */
	static public boolean isOpen(DateTime time) {
		if (time == null) {
			return false;
		}
		int week = time.getDayOfWeek();// 星期
		switch (week) {
		case 2:
		case 4:
		case 6:
			int hour = time.getHourOfDay();//
			return hour >= 8 && hour < 22;
		}
		return false;
	}

// XXX TEST 短时测试
//	static private boolean isOpen(DateTime time) {
//		if (time == null) {
//			return false;
//		}
//		// 每日2点开始 23点结束
////		int hour = time.getHourOfDay();
////		return hour >= 2 && hour < 23;
//		// 每小时5分开始
//		int minute = time.getMinuteOfHour();
//		return minute >= 5 && minute <= 59;
//		// 每5分一轮
////		int minute = time.getMinuteOfHour() % 5;
////		return minute >= 2 && minute <= 4;
//	}

	private Collection<TimeFrame> openTimes(DateTime time) {
		DateTime time2 = time.withTimeAtStartOfDay().withDayOfWeek(2).withHourOfDay(8);
		DateTime time4 = time.withTimeAtStartOfDay().withDayOfWeek(4).withHourOfDay(8);
		DateTime time6 = time.withTimeAtStartOfDay().withDayOfWeek(6).withHourOfDay(8);
		time2 = time2.isBefore(time) ? time2.plusWeeks(1) : time2;
		time4 = time4.isBefore(time) ? time4.plusWeeks(1) : time4;
		time6 = time6.isBefore(time) ? time6.plusWeeks(1) : time6;
		ArrayList<TimeFrame> times = new ArrayList<>();
		times.add(new TimeFrame(time2, time2.withHourOfDay(22)));
		times.add(new TimeFrame(time4, time4.withHourOfDay(22)));
		times.add(new TimeFrame(time6, time6.withHourOfDay(22)));
		return times;
	}

	public DateTime openTime(DateTime time) {
		DateTime next = null;
		for (TimeFrame timeFrame : openTimes(time)) {
			if (next == null) {
				next = timeFrame.getStartTime();
				continue;
			}
			if (timeFrame.getStartTime().isBefore(next)) {
				next = timeFrame.getStartTime();
			}
		}
		System.err.println(next);
		return next;
	}

	private void open(AreaBean areaBean, WorldBossModule module, DateTime now) {
		RankWorldBoss rankBoss = new RankWorldBoss(areaBean);
		rankBoss.clear();
		module.setCode(now.toString(DateTimeFormat.forPattern("yyyyMMddHHmm")));
		module.setTotalDamage(0);
	}

	private void settle(AreaBean areaBean, WorldBossModule module) {
		RankWorldBoss rankBoss = new RankWorldBoss(areaBean);
		rankReward(rankBoss);
		damageReward(rankBoss, module);
	}

	private void rankReward(RankWorldBoss rankBoss) {
		Map<String, menghuorankreward> all = DataCenter.getAllData(menghuorankreward.class);
		for (menghuorankreward rankdata : all.values()) {
			Collection<RankEntry> rankEntries = rankBoss.range(rankdata.getRankingmin(), rankdata.getRankingmax());
			Collection<Currency> rewards = Currency.create(rankdata.getRewardtype(), rankdata.getRewardid(), rankdata.getRewardnum());
			int rank = rankdata.getRankingmin();
			for (RankEntry entry : rankEntries) {
				String playerCode = entry.getKey();
				// 发邮件
				String title = GameString.七擒孟获排名奖励_title(rank).getText();
				String content = GameString.七擒孟获排名奖励_msg(rank).getText();
				new MailHandle().sendMail(playerCode, MailTypeEnum.Mail, title, content, CCReason.七擒孟获, rewards);
				rank++;
			}
		}
	}

	private void damageReward(RankWorldBoss rankBoss, WorldBossModule worldBossModule) {
		long totalDamage = worldBossModule.getTotalDamage();

		Map<String, menghuoreward> all = DataCenter.getAllData(menghuoreward.class);
		menghuoreward rewarddata = null;
		for (menghuoreward data : all.values()) {
			if (totalDamage < data.getCondition()) {
				continue;
			}
			if (rewarddata == null || rewarddata.getCondition() < data.getCondition()) {
				rewarddata = data;
			}
		}
		if (rewarddata == null) {
			return;
		}
		Collection<RankEntry> rankEntries = rankBoss.range(1, 0);
		Currencies rewards = new Currencies(Currency.create(rewarddata.getRewardtype(), rewarddata.getRewardid(), rewarddata.getRewardnum()));
		for (RankEntry entry : rankEntries) {
			String playerCode = entry.getKey();
			// 发邮件
			String title = GameString.七擒孟获总伤害奖励_title().getText();
			String content = GameString.七擒孟获总伤害奖励_msg(totalDamage).getText();
			new MailHandle().sendMail(playerCode, MailTypeEnum.Mail, title, content, CCReason.七擒孟获, rewards);
		}
	}

	/** 时间段 */
	public class TimeFrame {
		private DateTime startTime;
		private DateTime endTime;

		public TimeFrame(DateTime startTime, DateTime endTime) {
			this.startTime = startTime;
			this.endTime = endTime;
		}

		public DateTime getStartTime() {
			return startTime;
		}

		public DateTime getEndTime() {
			return endTime;
		}
	}
}
